<?php
/*
 * @Descripttion:
 * @version:
 * @Author: ewgof
 * @Date: 2020-09-02 07:08:50
 * @LastEditors: ewgof
 * @LastEditTime: 2020-12-04 15:36:38
 */
namespace app\http\controller\api;

use cw\File;

class Upload extends Base
{
    public function userUpload($request)
    {
        $token = $request->header('token');
        $host = $request->header('host');
        $index = $request->post('index');
        $watermark = $request->post('watermark', '');
        $compress = $request->post('compress', 'yes');  // 是否压缩图片
        $compress = $compress == 'yes' ? true : false;
        $uid = cache($token);

        if (empty($token)) {
            $msg = '上传图片失败--用户单图片上传失败：用户token为空。';
            echo $msg . PHP_EOL;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return api_json_return(10001);
        }
        $rst = \check_token($token);
        if ($rst !== true) {
            $msg = '上传图片失败--用户单图片上传失败：' . $rst['msg'];
            echo $msg . PHP_EOL;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return $rst;
        }

        // 生成文件MD5值，如果已经存在则直接返回不执行上传
        $upload_file_info = $request->file();
        $file_info = $this->hasFile($upload_file_info[$index]['tmp_name'], 1, $uid);
        // var_dump($file_info);return ;
        if ($file_info !== false) {
            return api_json_return(0, '', $file_info);
        }

        // 检查用户已使用空间
        $spaces_arr = $this->db->get('user_spaces', ['id', 'spaces'], ['uid' => $uid]);
        if ($spaces_arr) {
            $spaces = $spaces_arr['spaces'];
        } else {
            $spaces = 0;
        }
        // var_dump($token, cache($token), cache('user_spaces'), $spaces); return ;
        if ($spaces >= cache('user_spaces')) {
            return api_json_return(10007);
        }

        $web_config = cache('website_config');
        $size = $web_config['user_upload_size'];
        $number = $web_config['user_upload_number'];
        // var_dump($web_config, $size, $number);

        $path = __ROOT__ . 'upload/users/' . date('Ymd') . '/';

        $file = new File();
        $file->set('path', $path)->set('max_size', $size)->set('type', IMG_ALLOW_TYPE)->set('index', $index);
        // 上传
        $up_res = $file->upload($upload_file_info, $number, $compress);
        // var_dump($up_res);

        if ($up_res['code'] == 1200) {
            $img_path = strstr($up_res['filename'], '/upload');
            $insert_data = [
                'uid' => $uid,
                'url' => 'http://' . $host . $img_path,
                'filename' => $up_res['old_name'],
                'mime' => $up_res['mime'],
                'sha_md5' => md5_file($up_res['filename']),
                'created_at' => $this->t,
                'updated_at' => $this->t,
            ];

            $spaces += $up_res['size'];

            $this->db->pdo->beginTransaction();
            $res_u = $this->db->insert('user_imgs', $insert_data)->rowCount();
            $res_s = $this->db->update('user_spaces', ['spaces' => $spaces], ['id' => $spaces_arr['id']])->rowCount();

            if ($res_u === 1 && $res_s === 1) {
                $this->db->pdo->commit();

                // 图片添加水印
                if ($watermark) {
                    $this->addWaterMark($up_res['filename'], $watermark);
                }

                return api_json_return(0, '', ['url' => $insert_data['url'], 'filename' => $up_res['old_name']]);
            } else {
                $this->db->pdo->rollback();
                $msg = '上传图片失败--用户单图片上传失败：图片信息入库时失败。res_u => ' . $res_u . ', res_s => ' . $res_s . ', insert_data => ' . json_encode($insert_data) . ', spaces => ' . $spaces;
                echo $msg . PHP_EOL;
                log_msg($msg, 'error', $this->log_filename_apperr);
                return api_json_return(10006);
            }
        } else {
            $msg = '上传图片失败--用户单图片上传失败：' . $up_res['msg'];
            echo $msg . PHP_EOL;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return api_json_return(1, $up_res['msg']);
        }
    }


    public function guestUpload($request)
    {
        $index = $request->post('index', 'image');
        $watermark = $request->post('watermark', '');
        $host = $request->host();
        $compress = $request->post('compress', 'yes');  // 是否压缩图片
        $compress = $compress == 'yes' ? true : false;
        
        // 游客已使用空间
        $spaces_arr = $this->db->get('guest_spaces', ['id', 'spaces']);

        // var_dump($spaces_arr);
        if ($spaces_arr) {
            $spaces = $spaces_arr['spaces'];
        } else {
            $spaces = 0;
        }
        // var_dump($spaces);return ;
        if ($spaces >= ALL_GUEST_SPACES) {
            $del_size = $this->delSomeGuestImgs();
            if ($del_size) {
                $spaces = max(0, $spaces - $del_size);
            } else {
                $msg = '上传图片失败--游客图片上传失败：游客空间已满，删除图片过程出错。del_size => ' . $del_size;
                echo $msg . PHP_EOL;
                log_msg($msg, 'error', $this->log_filename_apperr);
                return api_json_return(10006);
            }
        }

        // 生成文件MD5值，如果已经存在则直接返回不执行上传
        $upload_file_info = $request->file();
        $file_info = $this->hasFile($upload_file_info[$index]['tmp_name'], 2);
        // var_dump($file_info);return ;
        if ($file_info !== false) {
            return api_json_return(0, '', $file_info);
        }
        

        // 游客上传图片的数量和大小
        $web_config = cache('website_config');
        $size = $web_config['guest_upload_size'];
        $number = $web_config['guest_upload_number'];

        $path = __ROOT__ . 'upload/guest/' . date('Ymd') . '/';

        $file = new File();
        $file->set('path', $path)->set('max_size', $size)->set('type', IMG_ALLOW_TYPE)->set('index', $index);
        // 上传
        $up_res = $file->upload($upload_file_info, $number, $compress);
        // var_dump($up_res);

        if ($up_res['code'] == 1200) {
            $img_path = strstr($up_res['filename'], '/upload');
            $insert_data = [
                'url' => 'http://' . $host . $img_path,
                'filename' => $up_res['old_name'],
                'mime' => $up_res['mime'],
                'sha_md5' => md5_file($up_res['filename']),
                'created_at' => $this->t,
                'updated_at' => $this->t,
            ];

            $this->db->pdo->beginTransaction();
            $res_gi = $this->db->insert('guest_imgs', $insert_data)->rowCount();
            $res_gs = $this->db->update('guest_spaces', ['spaces' => $spaces + $up_res['size']], ['id' => $spaces_arr['id']])->rowCount();
            // var_dump($res_gi, $res_gs);return ;
            if ($res_gi === 1 && $res_gs === 1) {
                $this->db->pdo->commit();
                // 图片添加水印
                if ($watermark) {
                    $this->addWaterMark($up_res['filename'], $watermark);
                }
                return api_json_return(0, '', ['url' => $insert_data['url'], 'filename' => $up_res['old_name']]);
            } else {
                $this->db->pdo->rollback();
                $msg = '上传图片失败--游客单图片上传失败：图片信息入库时失败。res_gi => ' . $res_gi . ', res_gs => ' . $res_gs . ', insert_data => ' . json_encode($insert_data);
                echo $msg . PHP_EOL;
                log_msg($msg, 'error', $this->log_filename_apperr);
                return api_json_return(10006, $up_res['msg']);
            }
        } else {
            $msg = '上传图片失败--游客单图片上传失败：图片上传过程出错。msg => ' . $up_res['msg'];
            echo $msg . PHP_EOL;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return api_json_return(10006, $up_res['msg']);
        }
    }


    protected function delSomeGuestImgs()
    {
        $img_info = $this->db->select('guest_imgs', ['id', 'url', 'ORDER' => ['created_at' => 'ASC'], 'LIMIT' => GUEST_UPLOAD_NUMBER + 5]);
        $size = 0;
        $ids = array_column($img_info, 'id');
        $urls = array_column($img_info, 'url');

        $del_res = $this->db->delete('guest_imgs', ['id' => $ids]);
        if ($del_res !== false) {
            foreach ($urls as $uv) {
                $path = '.' . strstr($uv, '/upload');
                if (@unlink($path)) {
                    $size += filesize($path);
                }
            }
            return $size;
        } else {
            $msg = '删除图片失败：删除图片数据时失败。del_res => ' . $del_res;
            echo $msg . PHP_EOL;
            log_msg($msg, 'error', $this->log_filename_apperr);
            return false;
        }
    }



    public function hasFile(String $file, $type, $uid = null)
    {
        if (empty($file)) {
            return false;
        }
        $md5 = md5_file($file);
        if ($type == 1) {
            if (empty($uid)) {
                return false;
            }
            $table_name = 'user_imgs';
            $where = ['sha_md5' => $md5, 'uid' => $uid];

        } elseif ($type == 2) {
            $table_name = 'guest_imgs';
            $where = ['sha_md5' => $md5];
        } else {
            return false;
        }
        $info = $this->db->get($table_name, ['url', 'filename'], $where);
        if (!empty($info)) {
            return $info;
        } else {
            return false;
        }
    }



    public function addWaterMark(String $file, String $watermark)
    {
        $image = \think\Image::open($file);
        // 给原图左上角添加水印并保存water_image.png
        $image->text($watermark, \__ROOT__ . 'fonts/picbed.ttf', 56, '#cccccc', 5, 0, 30)->save($file);
    }
}
